package cn.demoncat.util.pay.wxpay.constant;

/**
 * 微信支付常量
 * 
 * @author 延晓磊
 *
 * @since 2019年9月24日
 */
public class WxpayConstant {

	/**
	 * 微信接口域名
	 */
	public static final String DOMAIN = "https://api.mch.weixin.qq.com";

	/**
	 * XML请求/响应体的根标签
	 */
	public static final String XML_ROOT = "xml";
	
	/**
	 * 给微信的成功回应
	 */
	public static final String RESPOND_XML_SUCCESS = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[SUCCESS]]></return_msg></xml>";
	/**
	 * 给微信的失败回应
	 */
	public static final String RESPOND_XML_FAIL = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[FAIL]]></return_msg></xml> ";
	
	/**
	 * 微信接口
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月15日
	 */
	public enum Api {
		PAY_PRE("100", "申请支付", DOMAIN + "/pay/unifiedorder"),
		PAY_QUERY("110", "支付查询", DOMAIN + "/pay/orderquery"), 
		PAY_CLOSE("120", "关闭支付", DOMAIN + "/pay/closeorder"), 
		REFUND("130", "申请退款", DOMAIN + "/secapi/pay/refund"), 
		REFUND_QUERY("140", "退款查询", DOMAIN + "/pay/refundquery"), 
		DOWNLOAD_BILL("150", "下载对账单", DOMAIN + "/pay/downloadbill"),
		DOWNLOAD_FLOW("160", "下载资金流水", DOMAIN + "/pay/downloadfundflow");

		// 编码
		private final String code;
		// 描述
		private final String name;
		// URL
		private final String url;

		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static Api getByCode(String code) {
			for (Api e : Api.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}

		Api(String code, String name, String url) {
			this.code = code;
			this.name = name;
			this.url = url;
		}

		public String getCode() {
			return code;
		}

		public String getUrl() {
			return url;
		}

		public String getName() {
			return name;
		}
	}
 
	/**
	 * 签名类型 
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月15日
	 */
	public static class SignType {
		public static final String MD5 = "MD5";
		public static final String SHA256 = "HMAC-SHA256";
	}

	/**
	 * 响应状态码
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月15日
	 */
	public static class ResponseCode {
		/**
		 * 响应码 - 成功
		 */
		public static final String SUCCESS = "SUCCESS";
		/**
		 * 响应码 - 失败
		 */
		public static final String FAIL = "FAIL";
	}

	/**
	 * 账单类型/收支类型
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月15日
	 */
	public enum BillType {
		// 成功支付的订单
		PAY("1","SUCCESS", "收入"),
		// 退款的订单
		REFUND("2","REFUND", "退款");
		 
		// 编码
		private final String code;
		// 账单类型
		private final String type;
		// 名称
		private final String name;
		
		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static BillType getByCode(String code) {
			for (BillType e : BillType.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}
		
		/**
		 * 根据type获取枚举
		 * 
		 * @param type
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static BillType getByType(String type) {
			for (BillType e : BillType.values()) {
				if (e.getType().equals(type)) {
					return e;
				}
			}
			return null;
		}
		
		BillType(String code, String type, String name) {
			this.code = code;
			this.type = type;
			this.name = name;
		}
		public String getCode() {
			return code;
		}
		public String getType() {
			return type;
		}
		public String getName() {
			return name;
		}
	}
	
	/**
	 * 收支类型（资金流水类型）
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月15日
	 */
	public enum FlowType {
		
		INCOME("1", "收入"),
		EXPEND("2", "支出");
		 
		// 编码
		private final String code;
		// 名称
		private final String name;
		
		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static FlowType getByCode(String code) {
			for (FlowType e : FlowType.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}
		
		/**
		 * 根据name获取枚举
		 * 
		 * @param name
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static FlowType getByName(String name) {
			for (FlowType e : FlowType.values()) {
				if (e.getName().equals(name)) {
					return e;
				}
			}
			return null;
		}
		
		FlowType(String code, String name) {
			this.code = code;
			this.name = name;
		}
		public String getCode() {
			return code;
		}
		public String getName() {
			return name;
		}
	}

	/**
	 * 资金账户类型
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月15日
	 */
	public enum AccountType {
		BASIC("1","Basic", "基本账户"),
		OPERATION("2","Operation", "运营账户"),
		FEES("3","Fees", "手续费账户");
		 
		// 编码
		private final String code;
		// 账户类型
		private final String type;
		// 名称
		private final String name;
		
		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static AccountType getByCode(String code) {
			for (AccountType e : AccountType.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}
		
		/**
		 * 根据type获取枚举
		 * 
		 * @param type
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static AccountType getByType(String type) {
			for (AccountType e : AccountType.values()) {
				if (e.getType().equals(type)) {
					return e;
				}
			}
			return null;
		}
		
		AccountType(String code, String type, String name) {
			this.code = code;
			this.type = type;
			this.name = name;
		}
		public String getCode() {
			return code;
		}
		public String getType() {
			return type;
		}
		public String getName() {
			return name;
		}
	}
	
	/**
	 * 支付类型
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年9月24日
	 */
	public enum TradeType {
		// 1 线上，2微信，* 方式
		NATIVE("121", "NATIVE", "扫码支付", "PC网站"), 
		APP("122", "APP", "APP支付", "APP"), 
		MWEB("123", "MWEB", "H5支付", "手机网站"), 
		JSAPI("124", "JSAPI", "JSAPI支付", "公众号/小程序");

		// 编码
		private final String code;
		// 支付类型
		private final String type;
		// 支付名称
		private final String name;
		// 场景描述
		private final String description;

		/**
		 * 根据类型获取枚举
		 * 
		 * @param type
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static TradeType getByType(String type) {
			return TradeType.valueOf(type);
		}

		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static TradeType getByCode(String code) {
			for (TradeType e : TradeType.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}

		TradeType(String code, String type, String name, String description) {
			this.code = code;
			this.type = type;
			this.name = name;
			this.description = description;
		}

		public String getCode() {
			return code;
		}

		public String getType() {
			return type;
		}

		public String getName() {
			return name;
		}

		public String getDescription() {
			return description;
		}
	}

	/**
	 * 交易状态
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年9月27日
	 */
	public enum TradeStatus {

		NOTPAY("10", "NOTPAY", "未支付"), 
		SUCCESS("21", "SUCCESS", "支付成功"), 
		PAYERROR("22", "PAYERROR", "支付失败"), 
		REFUND("23", "REFUND", "转入退款"), 
		CLOSED("40", "CLOSED", "已关闭");

		// 编码
		private final String code;
		// 状态
		private final String status;
		// 描述
		private final String msg;

		/**
		 * 根据状态获取枚举
		 * 
		 * @param status
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static TradeStatus getByStatus(String status) {
			return TradeStatus.valueOf(status);
		}

		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static TradeStatus getByCode(String code) {
			for (TradeStatus e : TradeStatus.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}

		TradeStatus(String code, String status, String msg) {
			this.code = code;
			this.status = status;
			this.msg = msg;
		}

		public String getCode() {
			return code;
		}

		public String getStatus() {
			return status;
		}

		public String getMsg() {
			return msg;
		}
	}

	/**
	 * 退款状态
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年9月27日
	 */
	public enum RefundStatus {

		PROCESSING("10", "PROCESSING", "退款中"), 
		SUCCESS("21", "SUCCESS", "退款成功"), 
		CHANGE("22", "CHANGE", "退款失败"), 
		REFUNDCLOSE("40", "REFUNDCLOSE", "已关闭");

		// 编码
		private final String code;
		// 状态
		private final String status;
		// 描述
		private final String msg;

		/**
		 * 根据状态获取枚举
		 * 
		 * @param status
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static RefundStatus getByStatus(String status) {
			return RefundStatus.valueOf(status);
		}

		/**
		 * 根据编码获取枚举
		 * 
		 * @param code
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2019年9月27日
		 */
		public static RefundStatus getByCode(String code) {
			for (RefundStatus e : RefundStatus.values()) {
				if (e.getCode().equals(code)) {
					return e;
				}
			}
			return null;
		}

		RefundStatus(String code, String status, String msg) {
			this.code = code;
			this.status = status;
			this.msg = msg;
		}

		public String getCode() {
			return code;
		}

		public String getStatus() {
			return status;
		}

		public String getMsg() {
			return msg;
		}
	}

}
